package com.monkeyboy.first.jmm;

/**
 * 描述：     演示可见性带来的问题
 * 如果不加volatile关键字，可能会出现如下几种情况
 * a=3,b=2
 * a=1,b=2
 * a=3,b=3
 * a=1,b=3:这种情况概率非常低：原因是由于b修改了对于其它线程可见，而a修改了却不可见，这中情况只需要给
 * b这一个变量加volatile关键字就行了，因为volatile是符合happens-before原则的，
 * 如果b=a这儿可见了那么之前的操作都是可见的，即使a不加volatile
 *
 * 出现第四种的情况就是线程之前的数据同步不及时的如果不加volatile，加入第二个线程在第一个线程还没有write到主内存的时候就读取，
 * 这时候读取到a的值就还是1
 *
 */
public class FieldVisibility {

    volatile int a = 1;
    volatile int b = 2;

    private void change() {
        a = 3;
        b = a;
    }


    private void print() {
        System.out.println("b=" + b + ";a=" + a);
    }

    public static void main(String[] args) {
        while (true) {
            FieldVisibility test = new FieldVisibility();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    test.change();
                }
            }).start();

            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    test.print();
                }
            }).start();
        }

    }


}
